<?php

class opensolr_events_solr_service extends opensolr_events_config{
    
    public function rebuild($nodes = FALSE){
        echo "<br />Using: " . $this->solr_server . "<br />";
        
        
        $solr_objs = array();
        foreach($nodes as $k=>$node){
            $solr_objs[] = $this->_process_node($node);
        }
        $res = $this->insert($solr_objs);
        echo "<br />Doing: " . count($solr_objs) . "<br />";
        
        $this->solr->commit();
    }

    public function update($node = FALSE){
        $solr_obj = $this->_process_node($node);
        $res = $this->insert(array($solr_obj));
        $this->solr->commit();
    }

    public function _process_node($node){
        $solr_obj = array();
        
        foreach($node as $k => $n){
            
            foreach($this->indexed_fields as $f){
                if(strpos($k, $f) !== FALSE){
                    if(strpos($k, "field_") === FALSE){
                        if($k == 'created' || $k == 'changed'){
                            $solr_obj[$k . '_i'] = $n;
                        }else{
                            if($k == 'nid'){
                                $solr_obj[$k] = $n;
                                $solr_obj['id'] = $n;
                            }else if($k != 'tnid'){
                                $solr_obj[$k . '_s'] = $n;
                                if($k == "body"){
                                    unset($solr_obj[$k . '_s']);
                                    $solr_obj[$k . '_t'] = $n['und'][0]['value'];
                                }
                                if($k == "title"){
                                    $solr_obj[$k . '_t'] = $n;
                                }
                                
                            }
                        }
                    }else{
                        // Assume all custom fields are string to save memory
                        $solr_obj = array_merge($this->_process_field($n, $k, "s"), $solr_obj);
                        
                        // Apply the custom field types
                        foreach($this->custom_indexed_fields as $field_name=>$field_type){
                            
                            if($k == $field_name){
                                
                                unset($solr_obj[$k . '_s']);
                                unset($solr_obj[$k . '_sm']);
                                
                                if($field_type == "COLLECTION"){
                                    $solr_obj = array_merge($this->_process_collections($n, $field_name), $solr_obj);
                                }
                                
                                if($field_type == "DATE"){
                                    $solr_obj[$k . '_d'] = $this->_get_solr_date($n['und'][0]['value']);
                                }
                                if($field_type == "GEOHASH"){
                                    $solr_obj[$k . '_s'] = $n['und'][0]['value'];
                                    $coords = $this->_get_coords_by_zip_code($n['und'][0]['value']);
                                    $solr_obj[$k . '_coords_l'] = (isset($coords)) ? $coords : "0,0";
                                }
                                if($field_type == "FULLTEXT"){
                                    $solr_obj[$k . '_t'] = $n['und'][0]['value'];
                                }
                            }
                        }
                    }
                }
            }
        }
        return $solr_obj;
    }

    public function _process_field($n, $k, $type = "s", $idx = FALSE){
        $solr_obj = array();
        if(count($n['und']) > 1){
            $solr_obj[$k . '_' . $idx .'_' . $type . 'm'] = array();
            foreach($n['und'] as $iter => $nund){
                $solr_obj[$k . '_' . $idx . '_' . $type . 'm'][$iter] = $nund['value'];
                
                if(isset($n['und'][$iter]['fid'])){
                    //unset($solr_obj[$k . '_' . $idx . '_' . $type . 'm']);
                    if(isset($n['und'][$iter]['alt'])){
                        $solr_obj[$k . '_attr_alt_' . $idx . '_tm'][$iter] = $n['und'][$iter]['alt'];
                    }
                    if(isset($n['und'][$iter]['title'])){
                        $solr_obj[$k . '_attr_title_' . $idx . '_tm'][$iter] = $n['und'][$iter]['title'];
                    }
                    $file_uri = file_create_url(file_load($n['und'][$iter]['fid'])->uri);
                    $file_uri_arr = explode(".", $file_uri);
                    $file_uri_ext = array_pop($file_uri_arr);
                    $file_uri_filename = implode(".", $file_uri_arr);
                    $file_large_uri = $file_uri_filename . "_0." . $file_uri_ext;
                    $solr_obj[$k . '_small_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['fid'])) ? $file_uri : '';
                    $solr_obj[$k . '_large_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['fid'])) ? $file_large_uri : '';
                    
                    
                    
                    $file_uri_arr_doi = explode("/", $file_uri);
                    $file_uri_doi_filename = array_pop($file_uri_arr_doi);
                    $file_uri_medium_thumb = implode("/", $file_uri_arr_doi) . "/styles/article-thumbnail-medium/public/" . $file_uri_doi_filename;
                    $file_uri_small_thumb = implode("/", $file_uri_arr_doi) . "/styles/article-thumbnail-small/public/" . $file_uri_doi_filename;
                    
                    $solr_obj[$k . '_small_thumb_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['fid'])) ? $file_uri_small_thumb : '';
                    $solr_obj[$k . '_medium_thumb_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['fid'])) ? $file_uri_medium_thumb : '';
                    
                    
                    
                    // Thumbnail and wide for Christ sake!
                    $file_uri_slideshow_thumb = implode("/", $file_uri_arr_doi) . "/styles/slideshow-thumbnail/public/" . $file_uri_doi_filename;
                    $file_uri_wide_thumb = implode("/", $file_uri_arr_doi) . "/styles/article-image-wide/public/" . $file_uri_doi_filename;
                    
                    $solr_obj[$k . '_slideshow_thumb_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['fid'])) ? $file_uri_slideshow_thumb : '';
                    $solr_obj[$k . '_wide_thumb_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['fid'])) ? $file_uri_wide_thumb : '';
                    
                    
                    
                
                }
                
                if(isset($n['und'][$iter]['tid'])){
                    //unset($solr_obj[$k . '_' . $idx . '_' . $type . 'm']);
                    $solr_obj[$k . '_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['tid'])) ? taxonomy_term_load($n['und'][$iter]['tid'])->name : '';
                }
                
                
                if(isset($n['und'][$iter]['target_id'])){
                    //unset($solr_obj[$k . '_' . $idx . '_' . $type . 'm']);
                    $solr_obj[$k . '_' . $idx . '_' . $type . 'm'][$iter] = (isset($n['und'][$iter]['target_id'])) ? entity_load_single('node', $n['und'][$iter]['target_id'])->title : '';
                    $solr_obj[$k . '_NID_' . $idx . '_' . $type . 'm'][$iter] = $n['und'][$iter]['target_id'];
                }
            }
            
        }else{
            $solr_obj[$k . '_' . $idx . '_' . $type] = $n['und'][0]['value'];
            
            if(isset($n['und'][0]['fid'])){
                unset($solr_obj[$k . '_' . $idx . '_' . $type]);
                
                if(isset($n['und'][0]['alt'])){
                    $solr_obj[$k . '_attr_alt_' . $idx . '_t'] = $n['und'][0]['alt'];
                }
                if(isset($n['und'][0]['title'])){
                    $solr_obj[$k . '_attr_title_' . $idx . '_t'] = $n['und'][0]['title'];
                }
                
                $file_uri = file_create_url(file_load($n['und'][0]['fid'])->uri);
                $file_uri_arr = explode(".", $file_uri);
                $file_uri_ext = array_pop($file_uri_arr);
                $file_uri_filename = implode(".", $file_uri_arr);
                $file_large_uri = $file_uri_filename . "_0." . $file_uri_ext;
                
                $solr_obj[$k . '_small_' . $idx . '_' . $type] = (isset($n['und'][0]['fid'])) ? $file_uri : '';
                $solr_obj[$k . '_large_' . $idx . '_' . $type] = (isset($n['und'][0]['fid'])) ? $file_large_uri : '';
                
                $file_uri_arr_doi = explode("/", $file_uri);
                $file_uri_doi_filename = array_pop($file_uri_arr_doi);
                
                
                
                $file_uri_medium_thumb = implode("/", $file_uri_arr_doi) . "/styles/article-thumbnail-medium/public/" . $file_uri_doi_filename;
                $file_uri_small_thumb = implode("/", $file_uri_arr_doi) . "/styles/article-thumbnail-small/public/" . $file_uri_doi_filename;
                
                $solr_obj[$k . '_small_thumb_' . $idx . '_' . $type] = (isset($n['und'][0]['fid'])) ? $file_uri_small_thumb : '';
                $solr_obj[$k . '_medium_thumb_' . $idx . '_' . $type] = (isset($n['und'][0]['fid'])) ? $file_uri_medium_thumb : '';
                
                
                
                
                // Thumbnail and wide
                $file_uri_slideshow_thumb = implode("/", $file_uri_arr_doi) . "/styles/slideshow-thumbnail/public/" . $file_uri_doi_filename;
                $file_uri_wide_thumb = implode("/", $file_uri_arr_doi) . "/styles/article-image-wide/public/" . $file_uri_doi_filename;
                
                $solr_obj[$k . '_slideshow_thumb_' . $idx . '_' . $type] = (isset($n['und'][0]['fid'])) ? $file_uri_slideshow_thumb : '';
                $solr_obj[$k . '_wide_thumb_' . $idx . '_' . $type] = (isset($n['und'][0]['fid'])) ? $file_uri_wide_thumb : '';
                
            }
            
            if(isset($n['und'][0]['tid'])){
                unset($solr_obj[$k . '_' . $idx . '_' . $type]);
                $solr_obj[$k . '_' . $idx . '_' . $type] = (isset($n['und'][0]['tid'])) ? taxonomy_term_load($n['und'][0]['tid'])->name : '';
            }
            
            if(isset($n['und'][0]['target_id'])){
                unset($solr_obj[$k . '_' . $idx . '_' . $type]);
                $solr_obj[$k . '_' . $idx . '_' . $type . 'm'][0] = (isset($n['und'][0]['target_id'])) ? entity_load_single('node', $n['und'][0]['target_id'])->title : '';
                $solr_obj[$k . '_NID_' . $idx . '_' . $type . 'm'][0] = $n['und'][0]['target_id'];
            }
        }
        return $solr_obj;
    }

    // Process multidimensional collections
    public function _process_collections($n, $collection_name = FALSE){
        $prefix = "";
        if($collection_name !== FALSE){
            $prefix = "collection-" . $collection_name . "-";
        }
        
        $solr_obj = array();
        if(count($n['und']) > 1){
            foreach($n['und'] as $idx => $nund_c){
                
                $collection = field_collection_item_load($n['und'][$idx]['value']);
                
                foreach($collection as $coll_k => $coll_v){
                    
                    if(strpos($coll_k, "field_") !== FALSE && is_array($coll_v)){
                        
                        $solr_obj = array_merge($this->_process_field($coll_v, $prefix . $coll_k, "s", $idx), $solr_obj);
                        
                        foreach($this->custom_indexed_fields as $field_name_c=>$field_type_c){
    
                            if($coll_k == $field_name_c){
                        
                                unset($solr_obj[$prefix . $coll_k . '_' . $idx . '_s']);
                                unset($solr_obj[$prefix . $coll_k . '_' . $idx . '_sm']);
                                
                                if($field_type_c == "DATE"){
                                    $solr_obj[$prefix . $coll_k . '_' . $idx . '_d'] = $this->_get_solr_date($coll_v['und'][0]['value']);
                                }
                                if($field_type_c == "GEOHASH"){
                                    $solr_obj[$prefix . $coll_k . '_' . $idx . '_s'] = $coll_v['und'][0]['value'];
                                    $coords = $this->_get_coords_by_zip_code($coll_v['und'][0]['value']);
                                    $solr_obj[$prefix . $coll_k . '_' . $idx . '_coords_l'] = (isset($coords)) ? $coords : "0,0";
                                }
                                if($field_type_c == "FULLTEXT"){
                                    $solr_obj = array_merge($this->_process_field($coll_v, $prefix . $coll_k, "t", $idx), $solr_obj);
                                }
                            }
                        }
                    }
                    
                }
            }
        }else{
            $collection = field_collection_item_load($n['und'][0]['value']);
            
            foreach($collection as $coll_k => $coll_v){
                
                if(strpos($coll_k, "field_") !== FALSE && is_array($coll_v)){
                        
                    $solr_obj = array_merge($this->_process_field($coll_v, $prefix . $coll_k, "s"), $solr_obj);
                    
                    foreach($this->custom_indexed_fields as $field_name_c=>$field_type_c){

                        if($coll_k == $field_name_c){
                    
                            unset($solr_obj[$prefix . $coll_k . '_s']);
                            unset($solr_obj[$prefix . $coll_k . '_sm']);
                            
                            if($field_type_c == "DATE"){
                                $solr_obj[$prefix . $coll_k . '_d'] = $this->_get_solr_date($coll_v['und'][0]['value']);
                            }
                            if($field_type_c == "GEOHASH"){
                                $solr_obj[$prefix . $coll_k . '_s'] = $coll_v['und'][0]['value'];
                                $coords = $this->_get_coords_by_zip_code($coll_v['und'][0]['value']);
                                $solr_obj[$prefix . $coll_k . '_coords_l'] = (isset($coords)) ? $coords : "0,0";
                            }
                            if($field_type_c == "FULLTEXT"){
                                $solr_obj = array_merge($this->_process_field($coll_v, $prefix . $coll_k, "t"), $solr_obj);
                            }
                        }
                    }
                }
            }
        }
        return $solr_obj; 
    }


    public function insert($parts){
        $documents = array();
        if(is_array($documents)){
            foreach ( $parts as $item => $fields ) {
              $part = new Apache_Solr_Document();
              $fields = (array)$fields;
              if(is_array($fields)){
                  foreach ( $fields as $key => $value ) {
                      if ( is_array( $value ) ) {
                          foreach ( $value as $datum ){
                              $part->addField($key, $datum);
                          }
                      }else{
                          $part->$key = $value;
                      }
                  }
              }
              $documents[] = $part;
            }try{
              $ret = $this->solr->addDocuments( $documents );
            }catch(Exception $e){
              print_r($e->getMessage());
              return $e->getMessage();
            }
        }else{
            echo "Data Structure Not Valid";
            return FALSE;
        }
    }

    
    
    public function _log($msg){
        file_put_contents("/tmp/opensolr_events.log", date("F d Y - H:i:s") . ": " . $msg, FILE_APPEND | LOCK_EX);
    }


    public function _get_solr_date($date_string = FALSE){
        if($date_string == FALSE){
            return date("Y-m-d\TH:i:s\Z");
        }
        $timestamp = strtotime($date_string);
        if($timestamp !== FALSE && $timestamp != -1){
            return date("Y-m-d\TH:i:s\Z", $timestamp);
        }else{
            return date("Y-m-d\TH:i:s\Z");
        }
    }
    
    public function _get_coords_by_zip_code($zip_code = FALSE){
        if($zip_code == FALSE){
            return FALSE;
        }
        try{
            $url = $this->geohash_server . "?zip_code=" . $zip_code . "&country_code=US&within=50&group=place_name";
            $geohash = @json_decode(@file_get_contents($url));
            
            if($geohash->msg != "INVALID_PARAMETERS_OR_NO_RESULTS_FOUND"){
                if(trim($geohash->search_results[0]->coords)){
                    return trim($geohash->search_results[0]->coords);
                }else{
                    return "0,0";
                }
            }else{
                $url = $this->geoash_server_by_address . "?zip_query=" . $zip_code;
                $geohash = @json_decode(@file_get_contents($url));
                if($geohash->msg != "INVALID_PARAMETERS_OR_NO_RESULTS_FOUND"){
                    if(trim($geohash->search_results[0]->coords)){
                        return trim($geohash->search_results[0]->coords);
                    }else{
                        return "0,0";
                    }
                }else{
                    return "0,0";
                }
            }
            
        }catch(exception $e){
            return "0,0";
        }
    }
    
    public function _curl_post($target_url, $params = array(), $file = FALSE){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$target_url);
        curl_setopt($ch, CURLOPT_POST,1);
        if($file !== FALSE){
            $params['userfile'] = '@'.$file;
        }
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        $result = curl_exec ($ch);
        curl_close ($ch);
        return $result;
    }
    
    public function delete_record($nid){
        file_get_contents($this->solr_server . "/update?commit=true&optimize=true&maxSegments=2&waitFlush=false&wt=json&indent=true&stream.body=<delete><query>nid:" . $nid . "</query></delete>");
        $this->_log($res);
        return $res;
    }
    
    public function reset(){
        file_get_contents($this->solr_server . "/update?commit=true&optimize=true&maxSegments=2&waitFlush=false&wt=json&indent=true&stream.body=<delete><query>*:*</query></delete>");
        $this->_log($res);
        return $res;
    }
    
    public function optimize(){
        $res = file_get_contents($this->solr_server . "/update?commit=true&optimize=true&maxSegments=2&waitFlush=false&wt=json&indent=true");
        $this->_log($res);
        return $res;
    }
    
    public function commit(){
        $res = file_get_contents($this->solr_server . "/update?commit=true&optimize=false&maxSegments=2&waitFlush=false&wt=json&indent=true");
        $this->_log($res);
        return $res;
    }
}